// Copyright (c) 2009 Mike Haight, Andy Kipp
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

#include "stdafx.h"

using namespace System::IO;
using namespace System::Xml;
using namespace System::Xml::Serialization;

Layer::Layer()
{
}


String^ Layer::Name::get(void)
{
    return mName;
}


Map^ Layer::Map::get(void)
{
    return mMap;
}


List<WorldObject^>^ Layer::GetObjects(Coordinates::Rectangle argRectangle)
{
    List<WorldObject^>^ objectList = gcnew List<WorldObject^>();

    // TODO: The square size should be a const somewhere
    int left = (int)(argRectangle.X / 32);
    int top = (int)(argRectangle.Y / 32);
    int width = (int)(argRectangle.Width / 32);
    int height = (int)(argRectangle.Height / 32);

    if (left < 0)
        left = 0;

    if (top < 0)
        top = 0;

    if (height < 1)
        height++;

    if (width < 1)
        width++;

    for (int x = left; x <= left + width; x++)
    {
        for (int y = top; y <= top + height; y++)
        {
            Tile^ tile = mMap->GetSquare(x,y);
            if (tile != nullptr)
                objectList->Add(tile);
        }
    }

    return objectList;
}


void Layer::ReadXml(XmlReader^ reader) 
{
    // Load XmlDocument
    XmlDocument doc;
    doc.Load(reader);

    // Get Layer Element Attributes
    mName = doc.DocumentElement->GetAttribute("Name");

    // Read Layer Element
    {
        for each (XmlNode^ child in doc.DocumentElement)
        {
            if (child->NodeType != XmlNodeType::Element)
                continue;

            XmlElement^ e = safe_cast<XmlElement^>(child);

            if (e->Name->Equals("Map"))
            {
                // Load Map
                mMap = Game::Map::Load(ResourceManager::GetMap(e->GetAttribute("Name")));
            }
            else
            {
                throw gcnew XmlException(String::Format("Invalid XmlElement name: {0}", e->Name));
            }
        }
    }

    smLogger->Info("Loaded Layer: " + mName);
}


void Layer::WriteXml(XmlWriter^ writer)
{
    throw gcnew System::NotImplementedException();
}


XmlSchema^ Layer::GetSchema(void)
{
    return nullptr;
}
